Fixes #3023 - BREAKING CHANGE - Configurable key bindings via ConfigurationManager#4824
Merged
Conversation
Introduce ApplicationKeyboardThreadSafetyTests to verify thread-safety under various concurrent scenarios, including concurrent addition, invocation, event subscription, property mutation, and disposal. Tests use multiple threads to stress the API and assert no unexpected exceptions occur. Shared/static state is restored after tests to prevent side effects. This ensures ApplicationKeyboard is robust against race conditions in multi-threaded environments.
- Move all tests that mutate static state (e.g., Application.DefaultKeyBindings, Trace) into dedicated, non-parallelizable files/namespaces to prevent cross-test interference. - Move and update TestLogging helper to UnitTests.Parallelizable for consistent logging in tests. - Clean up KeyboardTests.cs by relocating setter tests to KeyboardSetterTests.cs. - Add try/finally blocks to restore static state in tests that mutate it. - Update usings and namespaces for clarity and parallelization. - Add comments and safeguards to prevent accidental static state pollution. - Enable safe parallel execution for the majority of the test suite, improving reliability and performance.
The Keyboard directory exclusion was preventing moved test files from being discovered by the test runner. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… generic type names, fix ListView layer order, apply DateEditor/TimeEditor bindings, update docs - Make Bind class public so consumers can configure DefaultKeyBindings - Fix Trace.Keyboard to use string.Join instead of .ToString() on IEnumerable - Strip generic arity suffix in ApplyKeyBindings (TreeView\1 -> TreeView) - Fix ListView to apply its layer before base layer (Home/End override) - Add ApplyKeyBindings call in DateEditor/TimeEditor constructors - Update DefaultKeyBindingsChanged doc noting mutation limitation - Fix config.md JSON examples to use proper nested structure - Update TreeView/ListView comments for clarity Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
Author
|
@tznind what are your thoughts on this new design? |
tznind
reviewed
Mar 13, 2026
BDisp
approved these changes
Mar 13, 2026
BDisp
left a comment
Collaborator
There was a problem hiding this comment.
This very arduous work seems perfect to me. I only asked a question.
… feature/cm-keybindings
- Use explicit EventArgs<T> and ValueChangedEventArgs<T> in event invocations for clarity and type safety. - Replace Tracing.Trace with Trace for tracing calls; add global using for Terminal.Gui.Tracing. - Remove obsolete PlatformDetection.GetCurrentPlatformName and its test. - Clean up unused usings and improve code consistency.
Refactored DriverRegistry for conciseness by using expression-bodied members and single-line record declarations. Updated built-in driver registration to a more compact style. Changed GetDefaultDriver to return the "ANSI" driver by default on Windows platforms instead of the "WINDOWS" driver.
Member
Author
Since I forgto before, I also made ansi the default driver on all patforms here., |
tig
added a commit
to tig/Terminal.Gui
that referenced
this pull request
Mar 24, 2026
Resolves merge conflicts from v2_develop changes: - tui-cs#4836: Lazy Adornment Views (IAdornment + IAdornmentView split) - tui-cs#4835: Adornment transparency - tui-cs#4824: Configurable key bindings - tui-cs#4845: Test project restructuring Adapted TabView/TabRow to new AdornmentImpl architecture: - Padding.Add -> Padding.GetOrCreateView().Add - Border.Frame -> Border.GetFrame() - Border.GetBorderRectangle -> BorderView.GetBorderBounds (made internal) - Adornment type refs -> AdornmentView/AdornmentImpl - Added LineCanvas merge from Border/Padding SubViews into parent View - Fixed nullable LineStyle conversion in TabRow Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced May 1, 2026
This was referenced May 11, 2026
This was referenced May 21, 2026
This was referenced Jun 1, 2026
This was referenced Jun 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes
ConfigurationManager#3023ansidriver default on all platforms.Summary
Makes all built-in key bindings configurable via
ConfigurationManagerwith platform-specific support (Windows / Linux / macOS). The design is MEC-ready (Microsoft.Extensions.Configuration) to minimize future migration cost.What Changed (140 files, +4065/-1368)
New infrastructure:
PlatformKeyBindingPOCO record withAll/Windows/Linux/Macoskey slotsBindfactory class with ergonomic helpers:Bind.All(),Bind.AllPlus(),Bind.NonWindows(),Bind.Platform()TuiPlatformenum replacing string-based platform identificationKeyBindingSchemaConverterfor JSON serialization ofDictionary<Command, PlatformKeyBinding>View.ApplyKeyBindings()— layered binding resolution usingGetSupportedCommands()filterThree
[ConfigurationProperty]properties (the entire CM surface):Application.DefaultKeyBindings— app-level commands (Quit, Arrange, Tab navigation, Suspend, Refresh)View.DefaultKeyBindings— shared base layer (cursor nav, clipboard, selection, editing)View.ViewKeyBindings— per-view-type overrides merged dictionary13 views migrated with view-specific
DefaultKeyBindings:TextField, TextView, ListView, TreeView, HexView, DropDownList, LinearRange, DateEditor, TimeEditor, TabView, TableView, CharMap, ColorPicker
Breaking changes (Phase 12):
ApplicationKeyboard(QuitKey,ArrangeKey,NextTabStopKey, etc.) — replaced byApplication.DefaultKeyBindings[Command.Quit]dictionary patternPlatformKeyBindingstoresKey[]instead ofstring[](type-safe)BindandPlatformKeyBindingfromConfiguration/toInput/Keyboard/Application.GetDefaultKey(Command)andApplication.GetDefaultKeys(Command)helper methods addedOther improvements:
ConfigurationandDrawtrace categoriesArchitecture
Design Principles
PlatformKeyBindingApplyKeyBindings()checksGetSupportedCommands()filterPlatformKeyBindingmaps cleanly toIOptions<T>bindingExample user config.json
{ "Application.DefaultKeyBindings": { "Quit": { "All": ["Ctrl+Q"] }, "Suspend": { "Linux": ["Ctrl+Z"], "Macos": ["Ctrl+Z"] } }, "View.ViewKeyBindings": { "TextField": { "Undo": { "All": ["Ctrl+Z"] }, "DeleteCharRight": { "All": ["Delete"], "Linux": ["Ctrl+D"], "Macos": ["Ctrl+D"] } } } }Documentation Updated
keyboard.md— rewrote forDefaultKeyBindingsdictionary APIconfig.md— updated config examples and property referencesnavigation.md— replaced removedIKeyboard.*Keyproperty refsnewinv2.md— updated v2 migration notesarrangement.md,menus.md,migratingfromv1.md— fixed stale refsexample_config.json— comprehensive refresh with current propertiesPull Request checklist:
dotnet testbefore commit///style comments)